package com.ksyun.campus.metaserver.services;

import com.google.gson.Gson;
import com.ksyun.campus.metaserver.domain.InstanceInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.*;
import org.apache.zookeeper.CreateMode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.PreDestroy;

@Component
@Slf4j
public class RegistService implements ApplicationRunner {

    @Autowired
    private String ipAddress;

    @Value("${server.port}")
    private Integer port;

//    @Value("${node}")
    private String node=System.getProperty("node");

    @Autowired
    private Gson gson;

    @Autowired
    private CuratorFramework curatorFramework;

    public void registToCenter() {
        try {
            // 获取Zookeeper节点路径
            String zookeeperPath = "/ms";

            // 构建实例信息
            InstanceInfo instanceInfo = new InstanceInfo(ipAddress, port);
//            String instanceJson = instanceInfo.toString(); // 替换成实际构建实例信息的逻辑
            String instanceJson = gson.toJson(instanceInfo);
            // 创建Zookeeper节点并设置实例信息
            // creatingParentsIfNeeded():如果父节点不存在，则创建父节点
            // 为实例创建临时节点
            curatorFramework.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(zookeeperPath+"/"+node, instanceJson.getBytes());
            // 打印注册成功信息
            log.info("成功注册实例到Zookeeper.");
        } catch (Exception e) {
            // 打印注册失败信息
            log.info("注册实例到Zookeeper失败: " + e.getMessage());
        }
    }


    @Override
    public void run(ApplicationArguments args) throws Exception {
        registToCenter();
        ListenDS();
    }

    @PreDestroy
    public void unregisterFromCenter() {
        try {
            // 获取ZooKeeper节点路径
            String zookeeperPath = "/ms";

            // 构建完整的节点路径
            String nodePath = zookeeperPath + "/" + node;

            // 检查节点是否存在
            if (curatorFramework.checkExists().forPath(nodePath) != null) {
                // 删除节点
                curatorFramework.delete().forPath(nodePath);
                // 打印删除成功信息
                log.info("成功删除注册节点: {}", nodePath);
            } else {
                // 节点不存在，打印节点不存在信息
                log.info("注册节点不存在: {}", nodePath);
            }
        } catch (Exception e) {
            // 打印删除失败信息
            log.info("删除注册节点失败: {}", e.getMessage());
        }
    }

    public void ListenDS() {
        try {
            // 获取Zookeeper节点路径
            String zookeeperPath = "/ds";

            // 创建NodeCache监听器
            TreeCache treeCache = new TreeCache(curatorFramework, zookeeperPath);

            // 注册节点监听器
            treeCache.getListenable().addListener(new TreeCacheListener() {
                @Override
                public void childEvent(CuratorFramework curatorFramework, TreeCacheEvent treeCacheEvent) throws Exception {
                    TreeCacheEvent.Type eventType = treeCacheEvent.getType();
                    // 获取节点数据
                    ChildData childData = treeCacheEvent.getData();
                    if (childData == null) {
                        // 节点数据为空，不处理
                        return;
                    }

                    // 获取节点路径
                    String nodePath = childData.getPath();

                    switch (eventType) {
                        case NODE_ADDED:
                            // 节点添加逻辑
                            System.out.println("节点添加: " + nodePath);
                            break;
                        case NODE_REMOVED:
                            // 节点移除逻辑
                            System.out.println("节点移除: " + nodePath);
                            break;
                        case NODE_UPDATED:
                            // 节点更新逻辑
                            System.out.println("节点更新: " + nodePath);
                            break;
                        default:
                            break;
                    }
                }
            });

            treeCache.start();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
